import { ElMessage } from 'element-plus';
// import { debounce, query } from '@/common.js'
export let BaseUrl = import.meta.env.MODE == 'development' ? '' : `${window.location.protocol}//${window.location.host}`
// 基础的fetch请求
function baseFetch(url = '', params = {}, options = {}, timeout = 8e3, reject) {
  url = url.slice(0, 4) == 'http' ? url : `${BaseUrl}${url}`
  const controller = new AbortController() // #注释
  const signal = controller.signal; // #注释
  const timer = setTimeout(() => {controller.abort();reject();}, timeout) // #注释
  const fetchOpts = {
    method: options.method || 'GET', // 设置请求方法为POST
    headers: {
      ...(options.headers || {}),
    },
    signal, // #注释
    mode: 'cors',
  };
  if (options.method != 'GET') {
    if (!(params instanceof FormData)) {
      params = JSON.stringify(params)
    }
    fetchOpts.body = params;
  }
  return fetch(url, fetchOpts).finally(() => clearTimeout(timer)); // #注释
  // return Promise.race([fetch(url, fetchOpts), new Promise((_, reject) => setTimeout(() => reject(new Error(`${url}请求超时`)), timeout))]) // #反注释
}
// 处理返回的结果
function processResult(type, res, resolve, reject, url) {
  if (type != 'data') { return resolve(res) }
  if (res.code != 0 && res.code != 200) {
    const msg = res.msg || `${url}报错，errmsg为空`
    ElMessage.error(msg);
    reject(msg)
  }
  resolve(res.result || res.data)
}
// 封装一个post请求
export async function post(url, params = {}, type = 'data', timeout) {
  return new Promise(async (resolve, reject) => {
    const response = await baseFetch(url,params,{ method: 'POST' },timeout,reject)
    const res = await response.json(); // 解析返回的JSON数据
    processResult(type, res, resolve, reject, url)
  });
}
//封装一个post请求用来发送formdata数据
export function postFormData(url, params = {}, type = 'data') {
  return new Promise(async (resolve, reject) => {
    const response = await baseFetch(url,params,{ method: 'POST' },undefined,reject)
    const res = await response.json(); // 解析返回的JSON数据
    processResult(type, res, resolve, reject, url);
  });
}
// 封装一个get请求
export const get = function (url, params = {}, type = 'data') {
  return new Promise(async (resolve, reject) => {
    const response = await baseFetch(url,params,{ method: 'GET' },undefined,reject)
    const res = await response.json(); // 解析返回的JSON数据
    processResult(type, res, resolve, reject, url)
  });
};
/**
 * 可以重复请求，连续重复的url请求，只会渲染最后一次请求返回的结果。主要用于查询操作
 * @param {String} url 请求的url地址
 * @param {Object} params 请求参数
 * @param {*} type 返回数据类型  1代表只返回data    0代表不做任何处理直接返回格式：{code:xx, data:xx, msg:xx}
 * @returns
 * @举例 const res = await _.endGet('/apprepair/editRepair', {id:1, name:'zz'})
 */
export const endGet = (function () {
  const reqRecord = new Map(); // 记录已发起但未返回的请求： url<---->reject方法
  let start = +new Date(); // 记录第一次点击时的时间戳
  return function (url, params, type = 'data') {
    url = url.slice(0, 4) == 'http' ? url : `${BaseUrl}${url}`
    let end = +new Date() // 记录第一次以后的每次点击的时间戳
    if (end - start > 30e3) { reqRecord.clear() } // 30s后将记录全部清除
    start = end
    const req = (reject) => baseFetch(url, params, { method: 'GET' }, undefined, reject).then(async (res) => await res.json())
    return new Promise((resolve, reject) => {
      if (reqRecord.get(url)) {
        reqRecord.get(url)(`放弃上次请求的渲染${url}`)
      } // 放弃请求
      const promiseA = new Promise((_, rej) => reqRecord.set(url, rej))
      return Promise.race([req(reject), promiseA]).then((res) =>
        processResult(type, res, resolve, reject, url)
      )
    })
  }
})()
// 封装request请求
export const request = function (url,params = {},options = { method: 'POST' },type = 'data') {
  return new Promise(async (resolve, reject) => {
    const response = await baseFetch(url, params, options, undefined, reject)
    const res = await response.json(); // 解析返回的JSON数据
    processResult(type, res, resolve, reject, url)
  });
};
// 获取https://xxxx.txt文本内容
export const getFileStr = function (url) {
  return new Promise(async (resolve, reject) => {
    const response = await baseFetch(url,undefined,undefined,undefined,reject)
    const res = await response.json() // 解析返回的JSON数据
    processResult(type, res, resolve, reject, url)
  });
};
// 下载二进制文件
export const downLoad = function (url, params) {
  const queryString = new URLSearchParams(params).toString()
  url = queryString ? `${url}?${queryString}` : url
  return new Promise(async (resolve, reject) => {
    const response = await baseFetch(url,params,{ method: 'GET' },undefined,reject)
    if (!response.ok) {
      throw new Error('Network response was not ok');
    } // 请求成功，处理返回的Response对象
    const res = await response.blob()
    resolve(res);
  })
}

/**
 * 防止重复请求，N毫秒内连续请求，只会请求一次。并且，第一次接口尚未返回则第二次请求被拒绝。主要用于新增操作
 * @param {*} url 请求的url地址
 * @param {*} params 请求参数
 * @param {*} type 返回数据类型  1代表只返回data    0代表不做任何处理直接返回格式：{code:xx, data:xx, msg:xx}
 * @returns
 * @举例 const res = await _.startPost('/apprepair/editRepair', {id:1, name:'zz'})
 */
export const startPost = (function (wait) {
  let start = +new Date(); // 记录第一次点击时的时间戳
  const reqRecord = new Map(); // 记录已发起但未返回的请求： url<--->reject方法
  return function (url, params, type = 'data') {
    url = url.slice(0, 4) == 'http' ? url : `${BaseUrl}${url}`
    let end = +new Date(); // 记录第一次以后的每次点击的时间戳
    if (end - start < wait && reqRecord.size != 0) {
      start = end;
      return Promise.reject(`取消当前请求${url}`)
    } // 执行处理函数后，将结束时间设置为开始时间，重新开始记时
    return new Promise(async (resolve, reject) => {
      if (reqRecord.get(url)) {
        return Promise.reject(`取消当前请求${url}`)
      }
      reqRecord.set(url, url);
      baseFetch(url, params, { method: 'POST' }, undefined, reject)
        .then(async (response) => {
          const res = await response.json(); // 解析返回的JSON数据
          processResult(type, res, resolve, reject, url)
        })
        .finally(() => reqRecord.delete(url))
    });
  };
})(1500);
/**
 * 可以重复请求，连续重复的url请求，只会渲染最后一次请求返回的结果。主要用于查询操作
 * @param {String} url 请求的url地址
 * @param {Object} params 请求参数
 * @param {*} type 返回数据类型  1代表只返回data    0代表不做任何处理直接返回格式：{code:xx, data:xx, msg:xx}
 * @returns
 * @举例 const res = await _.endPost('/apprepair/editRepair', {id:1, name:'zz'})
 */
export const endPost = (function () {
  const reqRecord = new Map(); // 记录已发起但未返回的请求： url<---->reject方法
  let start = +new Date(); // 记录第一次点击时的时间戳
  return function (url, params, type = 'data') {
    url = url.slice(0, 4) == 'http' ? url : `${BaseUrl}${url}`
    // console.log(url)
    let end = +new Date(); // 记录第一次以后的每次点击的时间戳
    if (end - start > 30e3) {
      reqRecord.clear()
    } // 30s后将记录全部清除
    start = end;
    const req = (reject) =>
      baseFetch(url, params, { method: 'POST' }, undefined, reject).then(
        async (response) => await response.json()
      );
    return new Promise((resolve, reject) => {
      if (reqRecord.get(url)) {
        reqRecord.get(url)(`放弃上次请求的渲染${url}`)
      } // 放弃请求
      const promiseA = new Promise((_, rej) => reqRecord.set(url, rej))
      return Promise.race([req(reject), promiseA]).then((res) =>
        processResult(type, res, resolve, reject, url)
      )
    })
  }
})()
